package com.simple.card.service.impl;

import com.simple.card.Utils.AesUtil;
import com.simple.card.Utils.IAuth;
import com.simple.card.Utils.TimeHelpUtil;
import com.simple.card.dataobject.KabaoUser;
import com.simple.card.dto.KaBaoUserDTO;
import com.simple.card.enums.ResultEnum;
import com.simple.card.exception.CreditException;
import com.simple.card.form.UserLoginForm;
import com.simple.card.repository.simplecard.KabaoUserRepository;
import com.simple.card.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService{

    private Integer loginTimeOut = 3600 * 24 * 7 * 1000;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @SuppressWarnings("all")
    @Autowired
    private KabaoUserRepository kabaoUserRepository;

    @Override
    public KabaoUser findByToken(String token) {
        return kabaoUserRepository.findUserByToken(token);
    }

    @Override
    public Integer save(KabaoUser kabaoUser) {
        kabaoUserRepository.save(kabaoUser);
        if(StringUtils.isEmpty(kabaoUser.getUid()+"")) {
            throw new CreditException(ResultEnum.USER_REGISTER_ERROR);
        }
        return kabaoUser.getUid();
    }

    @Override
    public Map<String,String> login(UserLoginForm userLoginForm){
        //校验手机验证码是否正确
        String code = redisTemplate.opsForValue().get(userLoginForm.getPhone());
        if(code == null) {
            throw new CreditException(ResultEnum.SMS_CODE_CHECK_FAILED);
        }
        if(!code.equals(userLoginForm.getCode())) {
            throw new CreditException(ResultEnum.SMS_CODE_CHECK_FAILED);
        }
        //查询数据库手机号是否存在
        KabaoUser kabaoUser = kabaoUserRepository.finUserByPhone(userLoginForm.getPhone());
        Map<String,String> map = new HashMap<>();
        if(kabaoUser == null) {
            //首次登录
            map = firstLogin(userLoginForm.getPhone());
            return map;
        }else {
            //最近登录
            map = lastLogin(userLoginForm.getPhone());
            return map;
        }
    }

    private HashMap<String,String> firstLogin(String phone) {
        //生成token值
        String token = IAuth.setAppLoginToken(phone);
        KabaoUser kabaoUser = new KabaoUser();
        kabaoUser.setPhone(phone);
        kabaoUser.setToken(token);
        kabaoUser.setTimeout(TimeHelpUtil.stampToDate(new Date().getTime() + loginTimeOut));
        kabaoUser.setCreateTime(new Date());
        kabaoUser.setUpdateTime(new Date());
        kabaoUser.setUsername("脑残粉-" + phone);
        kabaoUserRepository.save(kabaoUser);
        HashMap<String,String> map = new HashMap<>();
        if(kabaoUser.getUid() !=  null) {
            map.put("token", AesUtil.encryptData(token));
            return map;
        }else{
            throw new CreditException(ResultEnum.LOGIN_FAILED);
        }
    }

    private HashMap<String,String> lastLogin(String phone) {
        String token = IAuth.setAppLoginToken(phone);
        KabaoUser kabaoUser = new KabaoUser();
        kabaoUser.setUpdateTime(new Date());
        kabaoUser.setToken(token);
        kabaoUser.setTimeout(TimeHelpUtil.stampToDate(new Date().getTime() + loginTimeOut));
        kabaoUser.setPhone(phone);
        if(!kabaoUserRepository.updateKaBaoUser(kabaoUser)) {
            throw new CreditException(ResultEnum.LOGIN_FAILED);
        }
        HashMap<String,String> map = new HashMap<>();
        map.put("token", AesUtil.encryptData(token));
        return map;
    }

    @Override
    public KaBaoUserDTO findDTOByToken(String token) {
        KabaoUser kabaoUser = kabaoUserRepository.findUserByToken(token);
        KaBaoUserDTO kaBaoUserDTO = new KaBaoUserDTO();
        BeanUtils.copyProperties(kabaoUser,kaBaoUserDTO);
        return kaBaoUserDTO;
    }
}
